/**
 * @file mem_utils.c
 * @brief 安全内存操作工具实现
 * 
 * 实现动态内存检查、分配和释放功能。
 */

#include "mem_utils.h"
#include "log_utils.h"
#include "esp_log.h"
#include <string.h>

static const char *TAG = "mem_utils";

// 内存统计
static size_t total_allocated = 0;
static size_t allocation_count = 0;

/**
 * @brief 安全内存分配
 * 
 * @param size 分配大小
 * @param tag 标签（用于日志）
 * @return void* 分配的内存指针，失败返回NULL
 */
void* mem_utils_malloc(size_t size, const char *tag)
{
    if (size == 0) {
        ESP_LOGW(TAG, "尝试分配0字节内存");
        return NULL;
    }
    
    void *ptr = malloc(size);
    if (ptr == NULL) {
        ESP_LOGE(TAG, "内存分配失败，请求大小: %d bytes, 标签: %s", size, tag ? tag : "unknown");
        return NULL;
    }
    
    // 更新统计信息
    total_allocated += size;
    allocation_count++;
    
    ESP_LOGD(TAG, "分配内存: %p, 大小: %d bytes, 标签: %s", ptr, size, tag ? tag : "unknown");
    ESP_LOGD(TAG, "总计分配: %d bytes, 分配次数: %d", total_allocated, allocation_count);
    
    // 初始化内存为0
    memset(ptr, 0, size);
    
    return ptr;
}

/**
 * @brief 安全内存释放
 * 
 * @param ptr 内存指针的地址
 * @param tag 标签（用于日志）
 */
void mem_utils_free(void **ptr, const char *tag)
{
    if (ptr == NULL || *ptr == NULL) {
        ESP_LOGW(TAG, "尝试释放空指针, 标签: %s", tag ? tag : "unknown");
        return;
    }
    
    ESP_LOGD(TAG, "释放内存: %p, 标签: %s", *ptr, tag ? tag : "unknown");
    
    // 释放内存
    free(*ptr);
    
    // 清空指针
    *ptr = NULL;
}

/**
 * @brief 获取内存使用统计信息
 * 
 * @param allocated 已分配内存大小指针
 * @param count 分配次数指针
 */
void mem_utils_get_stats(size_t *allocated, size_t *count)
{
    if (allocated) {
        *allocated = total_allocated;
    }
    
    if (count) {
        *count = allocation_count;
    }
}

/**
 * @brief 重置内存统计信息
 */
void mem_utils_reset_stats(void)
{
    total_allocated = 0;
    allocation_count = 0;
    ESP_LOGI(TAG, "内存统计信息已重置");
}